/*
 * Momentum.java
 *
 * Copyright 2008 the Desert Labs Project (http://desertlabs.us)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package us.desertlabs.physics;

import java.math.BigDecimal;
import us.desertlabs.number.BigUtility;

/**
 * This is used to represent an amount of momentum. Momentum is present when
 * mass has velocity.
 *
 * @author Brandon Franklin
 */
public class Momentum extends DimensionalValue {

    /**
     * Given a <CODE>Mass</CODE> and <CODE>Velocity</CODE>, calculates and
     * returns the corresponding amount of <CODE>Momentum</CODE>.
     *
     * @param mass the <CODE>Mass</CODE>
     * @param velocity the <CODE>Velocity</CODE>
     * @return the <CODE>Momentum</CODE> resulting from moving the <CODE>Mass</CODE>
     *         at the supplied <CODE>Velocity</CODE>
     * @throws IllegalArgumentException if either of the parameters is invalid
     *         for any reason
     */
    static public Momentum calculate( final Mass mass, final Velocity velocity ) {

        // Validate the mass
        if( mass == null ) {
            throw new IllegalArgumentException( "Mass cannot be null." );
        }

        // Validate the velocity
        if( velocity == null ) {
            throw new IllegalArgumentException( "Velocity cannot be null." );
        } else if( !velocity.isValid() ) {
            throw new IllegalArgumentException( "Velocity is internally invalid." );
        }

        final BigDecimal bigDecMass = new BigDecimal( mass.toString() );
        final Number[] amounts = new Number[velocity.getDimensionality()];
        final Number[] rates = velocity.getRates();
        for( int i = 0; i < amounts.length; i++ ) {
            final BigDecimal rate = new BigDecimal( rates[i].toString() );
            amounts[i] = BigUtility.clipScale( bigDecMass.multiply( rate ) );
        }

        return new Momentum( amounts );
    }

    /**
     * Creates a new instance of <CODE>Momentum</CODE> with the specified
     * amounts of momentum in each dimension.
     *
     * @param values the amounts of momentum in each dimension
     * @throws IllegalArgumentException if the parameter is null or contains any
     *         null elements
     */
    public Momentum( final Number[] values ) {
        super( values );
    }
}
